home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume90
/
util
/
st
/
part01
/
serial.a
< prev
next >
Wrap
Text File
|
1990-06-04
|
6KB
|
334 lines
; Serial.a
; created by John Schultz, 17-Sep-89
; last modified 17-April-90
section Serial,CODE
xref _raw
xdef _baudper
xdef _openserial
xdef _closeserial
xdef _sendser
xdef _readser
xdef _checkser
xdef _rawtoascii
xdef _sendsernobuff
_LVOSetIntVector equ $FFFFFF5E
ESCAPE equ 69 ; input-handler rawkey code
CLOCK equ 3579545
_baudper dc.w (CLOCK/19200)-1 ; defaualt
CUSTOM equ $dff000
SERDATR equ $000018
SERDAT equ $000030
SERPER equ $000032
INTENA equ $00009a
INTENAR equ $00001c
INTREQ equ $00009c
TBEQSIZE equ 128 ; buffer size in bytes,
RBFQSIZE equ 128 ; increase or decrease as needed
LED equ $bfe001 ; toggle power led, audio filter
ledroll dc.b %00010001 ; flash every 4 bytes
ledpad dc.b 0
oldintena dc.w 0
tbequeue ds.b TBEQSIZE ; circular queue
tbeqend
tbehead dc.l tbequeue
tbetail dc.l tbequeue
oldtbeinterrupt dc.l 0
oldrbfinterrupt dc.l 0
tbeinterrupt
dc.l 0 ; ln_succ
dc.l 0 ; ln_prec
dc.b 2 ; NT_INTERRUPT
dc.b 127 ; ln_pri
dc.l 0 ; ln_name
dc.l tbehead ; is_data
dc.l tbehandler ; is_code
rbfinterrupt
dc.l 0 ; ln_succ
dc.l 0 ; ln_prec
dc.b 2 ; NT_INTERRUPT
dc.b 127 ; ln_pri
dc.l 0 ; ln_name
dc.l rbftail ; is_data
dc.l rbfhandler ; is_code
tbehandler
move.w #1,INTREQ(a0) ; clear TBE interrupt
move.l (a1),a1 ; a1 = tbehead, (a1) = pointer
cmp.l tbetail,a1 ; now a1 = pointer
beq.b 99$
move.w SERDATR(a0),d0 ; check to make sure emtpy
btst #13,d0
beq.b 99$
move.w #$100,d0
move.b (a1)+,d0 ; get byte from queue
move.w d0,SERDAT(a0) ; send byte
cmpa.l #tbeqend,a1
bne.b 10$
lea tbequeue(pc),a1
10$ move.l a1,tbehead
99$
rts
rbfqueue ds.b RBFQSIZE
rbfqend
rbfhead dc.l rbfqueue
rbftail dc.l rbfqueue
rbfhandler
move.w SERDATR(a0),d0 ; a0 = custom
move.w #$800,INTREQ(a0) ; clear RBF interrupt
move.l (a1),a0 ; a1 = rbftail, get pointer
move.b d0,(a0)+ ; write byte to buffer
cmpa.l #rbfqend,a0
bne.b 10$
lea rbfqueue(pc),a0
10$ move.l a0,(a1) ; a1 = rbftail
;99$
; move.b ledroll(pc),d0 ; remove from 99$-100$ for more
; rol.b #1,d0 ; speed
; move.b d0,ledroll
; btst #1,d0
; beq.b 100$
; bchg.b #1,LED ; toggle power led / audio filter
;100$
rts
_openserial
move.l a6,-(sp)
lea CUSTOM,a0
move.w #$4000,INTENA(a0) ; disable
move.l $4,a6 ; execbase
lea rbfinterrupt(pc),a1
moveq.l #11,d0
jsr _LVOSetIntVector(a6)
move.l d0,oldrbfinterrupt
lea tbeinterrupt(pc),a1
moveq.l #0,d0
jsr _LVOSetIntVector(a6)
move.l d0,oldtbeinterrupt
lea CUSTOM,a0
move.w _baudper,SERPER(a0) ; set period
move.w #$3fff,$bfd0fe ; init handshake lines
move.w INTENAR(a0),oldintena
move.w #$8801,INTENA(a0) ; turn on RBF and TBE INTENA
move.w #$0801,INTREQ(a0) ; clear RBF and TBE INTREQ
move.w #$c000,INTENA(a0) ; enable
move.l (sp)+,a6
rts
_closeserial
move.l a6,-(sp)
lea CUSTOM,a0
move.w #$4000,INTENA(a0) ; disable
move.l $4,a6 ; execbase
move.l oldrbfinterrupt,a1
moveq.l #11,d0
jsr _LVOSetIntVector(a6)
move.l oldtbeinterrupt,a1
moveq.l #0,d0
jsr _LVOSetIntVector(a6)
lea CUSTOM,a0
move.w #$0801,INTENA(a0) ; turn off RBF and TBE INTENA
move.w oldintena,d0
and.w #$0801,d0 ; mask for bit 11 and bit 1.
bset #15,d0 ; set/clr = 1 (set)
move.w d0,INTENA(a0) ; reset old RBF and TBE INTENA
bclr.b #1,LED
move.w #$0801,INTREQ(a0) ; clear RBF and TBE INTREQ
move.w #$c000,INTENA(a0) ; enable
move.l (sp)+,a6
rts
_sendser
lea CUSTOM,a0
move.w #$4000,INTENA(a0)
move.l tbetail,a1
cmpa.l tbehead,a1
beq.b 5$
move.w #$8001,INTREQ(a0) ; generate a tbe interrupt
5$
move.b d0,(a1)+ ; queue up byte
cmpa.l #tbeqend,a1
bne.b 10$
lea tbequeue(pc),a1
10$ move.l a1,tbetail
move.w #$c000,INTENA(a0)
rts
; send byte in d0 to serial port, non-buffered.
_sendsernobuff
lea CUSTOM,a0
move.w #$4000,INTENA(a0)
1$ move.w SERDATR,d1
btst #13,d1 ; check TBE
beq.b 1$ ; buffer busy
move.w #$100,d1
move.b d0,d1
move.w d1,SERDAT(a0)
2$ move.w SERDATR(a0),d1
btst #13,d1 ; check TBE
beq.b 2$ ; buffer busy
move.w #$001,INTREQ(a0) ; clear TBE interrupt
move.w #$c000,INTENA(a0)
rts
; uses a0
_readser
cmp.w #ESCAPE,_raw ; quits on ESC from input handler
beq.b 20$
move.l rbfhead,a0
cmpa.l rbftail,a0
beq.b _readser
move.b (a0)+,d0
cmpa.l #rbfqend,a0
bne.b 10$
lea rbfqueue(pc),a0
10$ move.l a0,rbfhead
20$
rts
_checkser
move.l rbfhead,a0
cmpa.l rbftail,a0
bne.b dataisin
moveq.l #0,d0
rts
dataisin
moveq.l #1,d0
rts
; rawkey in d0
; ascii returned in d0
_rawtoascii
cmp.b #79,d0
bls.b getascii
moveq.l #0,d0
rts
getascii
lea asciitable,a0
move.b 0(a0,d0),d0
rts
section asciitable,data
; This is a quick trick, don't do this for anything other than
; home use, boys and girls. Use rawkeyconvert, etc.
asciitable
dc.b '`' ; backquote `
dc.b '1'
dc.b '2'
dc.b '3'
dc.b '4'
dc.b '5'
dc.b '6'
dc.b '7'
dc.b '8'
dc.b '9'
dc.b '0'
dc.b '-'
dc.b '='
dc.b $0D ; \
dc.b 0
dc.b '0' ; keypad 0
dc.b 'q'
dc.b 'w'
dc.b 'e'
dc.b 'r'
dc.b 't'
dc.b 'y'
dc.b 'u'
dc.b 'i'
dc.b 'o'
dc.b 'p'
dc.b '['
dc.b ']'
dc.b 0
dc.b '1'
dc.b '2'
dc.b '3'
dc.b 'a'
dc.b 's'
dc.b 'd'
dc.b 'f'
dc.b 'g'
dc.b 'h'
dc.b 'j'
dc.b 'k'
dc.b 'l'
dc.b ';'
dc.b $27 ; ' single quote
dc.b 0
dc.b 0
dc.b '4'
dc.b '5'
dc.b '6'
dc.b 0
dc.b 'z'
dc.b 'x'
dc.b 'c'
dc.b 'v'
dc.b 'b'
dc.b 'n'
dc.b 'm'
dc.b ','
dc.b '.'
dc.b '/'
dc.b 0
dc.b '.' ; keypad
dc.b '7'
dc.b '8'
dc.b '9'
dc.b ' '
dc.b $8 ; backspace
dc.b $9 ; tab
dc.b $D ; enter cr
dc.b $D ; return cr
dc.b $1B ; ESC
dc.b $7f ; delete
dc.b ''
dc.b 0
dc.b 0
dc.b '-' ; keypad
dc.b 0
dc.b 0
dc.b $b ; up arrow
dc.b $a ; down arrow
dc.b $20 ; rt arrow
dc.b $8 ; left arrow
END